<template>
  <el-dialog
    :model-value="dialogVisible"
    :title="title"
    :width="width"
    @close="handleClose"
  >
    <el-form
      ref="formRef"
      :model="formData"
      :rules="formRules"
      :label-width="labelWidth"
      :label-position="labelPosition"
    >
      <template v-for="field in fields" :key="field.prop">
        <el-form-item
          :label="field.label"
          :prop="field.prop"
        >
          <!-- 输入框 -->
          <el-input
            v-if="field.type === 'input'"
            v-model="formData[field.prop]"
            :disabled="field.disabled"
            :placeholder="field.placeholder"
            :type="field.inputType || 'text'"
            clearable
            v-bind="field.attrs"
          />

          <!-- 选择器 -->
          <el-select
            v-else-if="field.type === 'select'"
            v-model="formData[field.prop]"
            :multiple="field.multiple"
            :placeholder="field.placeholder"
            :filterable="field.filterable"
            style="width: 100%"
            v-bind="field.attrs"
          >
            <el-option
              v-for="option in field.options"
              :key="option.value"
              :label="option.label"
              :value="option.value"
            />
          </el-select>
        </el-form-item>
      </template>

      <el-form-item>
        <el-button type="primary" @click="handleSubmit">{{ submitText }}</el-button>
        <el-button @click="handleReset">{{ resetText }}</el-button>
      </el-form-item>
    </el-form>
  </el-dialog>
</template>

<script setup>
import { ref, reactive, defineProps, defineEmits, watch } from 'vue'
import { ElMessage } from 'element-plus'

// 定义组件属性
const props = defineProps({
  // 对话框是否可见
  dialogVisible: {
    type: Boolean,
    default: false
  },
  // 对话框标题
  title: {
    type: String,
    default: '表单'
  },
  // 对话框宽度
  width: {
    type: String,
    default: '700px'
  },
  // 表单标签宽度
  labelWidth: {
    type: String,
    default: '100px'
  },
  // 表单标签位置
  labelPosition: {
    type: String,
    default: 'left'
  },
  // 表单字段配置
  fields: {
    type: Array,
    required: true,
    default: () => []
  },
  // 表单验证规则
  rules: {
    type: Object,
    default: () => ({})
  },
  // 初始表单数据
  initialData: {
    type: Object,
    default: () => ({})
  },
  // 提交按钮文本
  submitText: {
    type: String,
    default: '提交'
  },
  // 重置按钮文本
  resetText: {
    type: String,
    default: '重置'
  }
})

// 定义事件
const emit = defineEmits(['update:modelValue', 'close', 'submit', 'reset'])

// 表单引用
const formRef = ref(null)

// 表单数据
const formData = reactive({})

// 表单验证规则
const formRules = reactive(props.rules)

// 监听对话框显示状态
watch(() => props.dialogVisible, (newVal) => {
  if (newVal) {
    // 显示对话框时，初始化表单数据
    Object.assign(formData, props.initialData)
  }
})

// 关闭对话框
const handleClose = () => {
  formRef.value?.resetFields()
  emit('close')
}

// 提交表单
const handleSubmit = async () => {
  if (!formRef.value) return

  try {
    await formRef.value.validate()
    emit('submit', { ...formData })
  } catch (error) {
    ElMessage.error('请检查表单填写是否正确')
  }
}

// 重置表单
const handleReset = () => {
  formRef.value?.resetFields()
  emit('reset')
}
</script>

<style scoped>
.el-select {
  width: 100%;
}
</style>